﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace WebQQ批量挂QQ软件
{
    /// <summary>
    /// 加密解密类
    /// </summary>
    public class SymmetricMethod
    {
        private SymmetricAlgorithm EncryptionService;
        private string Key, IV;

        /// 
        /// 对称加密类的构造函数
        /// 
        public SymmetricMethod()
        {
            EncryptionService = new RijndaelManaged();
            Key = "1szetaddddddddddddddzkkgxvcvx;xszzxxxxxxxxxxxxxxxxfjupeikauincljasdi"; // 任意字符串
            IV = "xxoewkqopfkpkdaskfdsksdalksdfakklfsadkdfsaksadfldsafeeeeeeeeeeeeeek";//任意字符串
        }
        /// <summary>
        /// 对称加密类的构造函数,实例化初始化Key,Iv值
        /// </summary>
        /// <param name="key">密匙</param>
        public SymmetricMethod(string key)
        {
            EncryptionService = new RijndaelManaged();
            Key = key; // 任意字符串
            IV = "123123lxlcjiajkdslsidfjollddtyynbzxkkhisadofijfjweijljfsdffffffffffffffzalj";//任意字符串
        }

        /// <summary>
        /// 对称加密类的构造函数,实例化初始化Key,Iv值
        /// </summary>
        /// <param name="key">密匙</param>
        /// <param name="iv">向量IV</param>
        public SymmetricMethod(string key, string iv)
        {
            EncryptionService = new RijndaelManaged();//Rijndael 算法的托管版本,所有对称加密算法的所有实现必须从Rijndael继承。
            Key = key;
            IV = iv;
        }

        /// <summary>
        /// 写入或得到自定义的密匙KEY
        /// </summary>
        public string key
        {
            set
            {
                Key = value;
            }
            get
            {
                return Key;
            }
        }

        /// <summary>
        /// 写入或得到自定义的向量IV
        /// </summary>
        public string iv
        {
            set
            {
                IV = value;
            }
            get
            {
                return IV;
            }
        }

        /// <summary>
        /// 获得密钥
        /// </summary>
        /// <returns>密钥</returns>
        private byte[] GetKey()
        {
            string sTemp = Key;
            EncryptionService.GenerateKey();//生成随机KEY
            byte[] bytTemp = EncryptionService.Key;//把获取的密匙付值给BYTTEMP
            int KeyLength = bytTemp.Length;//获取元素总数
            if (sTemp.Length > KeyLength)//判断变量KEY的长度是否大于元素的总数
                sTemp = sTemp.Substring(0, KeyLength);//如果TRUE,那么从字符开始的地方截取以元素总数为最大限的字符。
            else if (sTemp.Length < KeyLength)//判断变量KEY的长度是否小于元素的总数
                sTemp = sTemp.PadRight(KeyLength, ' ');//左对齐STEMP字符串，并以空格来填充，长度达到元素的总数。
            return ASCIIEncoding.ASCII.GetBytes(sTemp);//对 Unicode 字符数组中或 String 中指定范围的字符进行编码(单个7位)，并将结果存储在指定的字节数组中。
        }

        /// <summary>
        /// 获得初始向量IV
        /// </summary>
        /// <returns>初始向量IV</returns>
        private byte[] GetIV()
        {
            string sTemp = IV;
            EncryptionService.GenerateIV();
            byte[] bytTemp = EncryptionService.IV;
            int IVLength = bytTemp.Length;
            if (sTemp.Length > IVLength)
                sTemp = sTemp.Substring(0, IVLength);
            else if (sTemp.Length < IVLength)
                sTemp = sTemp.PadRight(IVLength, ' ');
            return ASCIIEncoding.ASCII.GetBytes(sTemp);
        }

        /// <summary>
        /// 加密方法
        /// </summary>
        /// <param name="Source">待加密的串</param>
        /// <returns>经过加密的串</returns>
        public string Encrypto(string Source)
        {
            byte[] bytIn = UTF8Encoding.UTF8.GetBytes(Source);//对 Unicode 字符数组中或 String 中指定范围的字符进行编码(单个8位)，并将结果存储在指定的字节数组中，把结果付给字节数组。
            MemoryStream ms = new MemoryStream();//创建其支持存储区为内存的流。
            EncryptionService.Key = GetKey();//设置KEY的值.
            EncryptionService.IV = GetIV();//设置向量IV的值.
            ICryptoTransform encrypto = EncryptionService.CreateEncryptor();//创建基本的加密对象
            CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);//将MS流转换为加密流,以encrypto对流进行加密转换。CryptoStreamMode模式为写访问。
            cs.Write(bytIn, 0, bytIn.Length);//将BYTIN字节数组全部写入加密流。
            cs.FlushFinalBlock();//用缓冲区的当前状态更新基础数据源或储存库，随后清除缓冲区。
            ms.Close();//关闭MS流。
            byte[] bytOut = ms.ToArray();//将整个流内容写入字节数组并付给BYTOUT字节数组。
            return Convert.ToBase64String(bytOut);//将单个为8位的字节数组转换为字符串，并64为基的数字组成。
        }

        /// <summary>
        /// 解密方法
        /// </summary>
        /// <param name="Source">待解密的串</param>
        /// <returns>经过解密的串</returns>
        public string Decrypto(string Source)
        {
            byte[] bytIn = Convert.FromBase64String(Source);//把一个得到的64位为基数字组成的字符串转换为8位数组并付给一个字节数组。
            MemoryStream ms = new MemoryStream(bytIn, 0, bytIn.Length);//把字节数组写入流。
            EncryptionService.Key = GetKey();//设置KEY的值
            EncryptionService.IV = GetIV();//设置向量IV的值
            ICryptoTransform encrypto = EncryptionService.CreateDecryptor();//创建基本的加密对象
            CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Read);//将MS流转换为加密流,以encrypto对流进行加密转换。CryptoStreamMode模式为读访问。
            StreamReader sr = new StreamReader(cs);//从加密流中读取字符。
            return sr.ReadToEnd();//得到一个从加密流开始位置到结束的字符。
        }
    }
}
